﻿using Furion.EventBus;

namespace GoodAdmin.System;

public class UserEventSubscriber:IEventSubscriber,ISingleton
{
    private readonly IRedisCacheManager _redisCacheManager;
    private readonly IServiceProvider _service;

    public UserEventSubscriber(IRedisCacheManager redisCacheManager,IServiceProvider service)
	{
        _redisCacheManager = redisCacheManager;
        _service = service;
    }

    /// <summary>
    /// 根据menu id列表移除用户数据范围
    /// 主要用于菜单修改和删除时
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    [EventSubscribe(EventSubscriberConst.RemoveDataScopeByMenuIds)]
    public async Task RemoveUserDataScopeByMenuIds(EventHandlerExecutingContext context)
    {
        //获取菜单ID
        var menuIds = (List<long>)context.Source.Payload;
        if (menuIds.Count == 0) return;
        // 创建新的作用域
        using var scope = _service.CreateScope();
        // 解析关联关系服务
        var relationService = scope.ServiceProvider.GetRequiredService<IRelationService>();
        var roleIdList = (await relationService.GetRelationListByTargetId(CategoryConst.RELATION_ROLE_MENU, menuIds))
            .Select(it => it.ObjectId).Distinct().ToList();
        if (roleIdList.Count == 0) return;
        //再根据角色查询用户
        var userIdList = (await relationService.GetRelationListByTargetId(CategoryConst.RELATION_ROLE_USER, roleIdList))
            .Select(it => CacheConst.ApiRole+it.TargetId).Distinct().ToArray();
        if (userIdList.Length == 0) return;
         _redisCacheManager.Remove(userIdList);        
    }

    /// <summary>
    /// 根据role id列表移除用户数据范围
    /// 主要用于角色修改、删除、以及授权时
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    [EventSubscribe(EventSubscriberConst.RemoveDataScopeByRoleIds)]
    public async Task RemoveUserDataScopeByRoleIds(EventHandlerExecutingContext context)
    {
        //获取角色ID
        var roleIds = (long[])context.Source.Payload;
        if (roleIds.Length == 0) return;
        // 创建新的作用域
        using var scope = _service.CreateScope();
        // 解析关联关系服务
        var relationService = scope.ServiceProvider.GetRequiredService<IRelationService>();
        var userService = scope.ServiceProvider.GetRequiredService<ISysUserService>();
        var userRoleRelationList = await relationService.GetRelationListByObjectIdList(CategoryConst.RELATION_ROLE_USER, [.. roleIds]);
        //获取角色授权的组织id
        var orgRoleRelationList = await relationService.GetRelationListByObjectIdList(CategoryConst.RELATION_ROLE_ORG, [.. roleIds]);
        var orgIds = orgRoleRelationList.Select(it => it.TargetId).ToList();
        //根据组织id找到用户信息
        var user = await userService.GetUsersByField(orgIds,u=>u.OrgId);        
        var userIds = userRoleRelationList.Select(x => CacheConst.ApiRole + x.TargetId).Distinct().ToArray();
        userIds.AddRange(user.Select(it => CacheConst.ApiRole + it.Id).Distinct().ToArray());
        if (userIds.Length == 0) return;
        _redisCacheManager.Remove(userIds);
    }

    /// <summary>
    /// 根据用户id列表移除用户数据范围
    /// 主要用于角色授权用户时
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    [EventSubscribe(EventSubscriberConst.RemoveDataScopeByUserIds)]
    public async Task RemoveUserDataScopeByUserIds(EventHandlerExecutingContext context)
    {
        //获取角色ID
        var userIds = (long[])context.Source.Payload;
        if (userIds.Length == 0) return;
        // 创建新的作用域
        using var scope = _service.CreateScope();
        var userCacheIds = userIds.Select(id => CacheConst.ApiRole + id).Distinct().ToArray();
        if (userIds.Length == 0) return;
        await Task.Run(() =>
        {
            _redisCacheManager.Remove(userCacheIds);
        });
    }

    /// <summary>
    /// 根据组织id列表移除用户数据范围
    /// 主要用于角色授权组织时
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    [EventSubscribe(EventSubscriberConst.RemoveDataScopeByOrgIds)]
    public async Task RemoveUserDataScopeByOrgIds(EventHandlerExecutingContext context)
    {
        //获取组织ID
        var orgIds = (long[])context.Source.Payload;
        if (orgIds.Length == 0) return;
        // 创建新的作用域
        using var scope = _service.CreateScope();

        var userService = scope.ServiceProvider.GetRequiredService<ISysUserService>();
        //根据组织id找到用户信息
        var user = await userService.GetUsersByField([.. orgIds],u=>u.OrgId);
        var userIds = user.Select(it => CacheConst.ApiRole + it.Id).Distinct().ToArray();
        if (userIds.Length == 0) return;
        _redisCacheManager.Remove(userIds);
    }


    /// <summary>
    /// 根据职位id列表移除用户数据范围
    /// 主要用于角色授权职位时
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    [EventSubscribe(EventSubscriberConst.RemoveDataScopeByPositionIds)]
    public async Task RemoveUserDataScopeByPositionIds(EventHandlerExecutingContext context)
    {
        //获取职位ID
        var positionIds = (long[])context.Source.Payload;
        if (positionIds.Length == 0) return;
        // 创建新的作用域
        using var scope = _service.CreateScope();
        var userService = scope.ServiceProvider.GetRequiredService<ISysUserService>();
        //根据组织id找到用户信息
        var user = await userService.GetUsersByField([.. positionIds],u=>u.PositionId);
        var userIds = user.Select(it => CacheConst.ApiRole + it.Id).Distinct().ToArray();
        if (userIds.Length == 0) return;
        _redisCacheManager.Remove(userIds);
    }
}